package ${groupId}.${artifactIdProjectPackageName}.utils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class JsonUtils {
    private static Gson gson = new GsonBuilder().create();
    public static String toJson(Object obj) {

        return gson.toJson(obj);
    }

    public static <T> T fromJson(String json,Class<T> tClass) {
        return gson.fromJson(json, tClass);
    }

    public static <T> List<T> fromJsonToList(String json,Class<T> tClass) {
        List<T> ts = new ArrayList<>();
        JsonElement jsonElement = JsonParser.parseString(json);
        JsonArray asJsonArray = jsonElement.getAsJsonArray();
        for (JsonElement element : asJsonArray) {
            ts.add(gson.fromJson(element,tClass));
        }
        return ts;
    }

    private static Object getValue(Map map, String[] keys, int i){
        Object o = map.get(keys[i]);
        if(keys.length - 1 == i){
            return o;
        }
        if(o instanceof Map){
            return getValue((Map)o,keys,++i);
        }else{
            return o;
        }
    }

    private static final ConcurrentHashMap<String,Map> jsonMap = new ConcurrentHashMap<>();

    public static Object getValue(String json, String key){
        String jsonMd5 = DigestUtils.md5DigestAsHex(json.getBytes(StandardCharsets.UTF_8));
        Map map = jsonMap.get(jsonMd5);
        if(map == null){
            map = fromJson(json, Map.class);
            if(jsonMap.size() > 10){
                jsonMap.clear();
            }
            jsonMap.put(jsonMd5,map);
        }

        if(!key.contains(".")){
            return map.get(key);
        }
        return getValue(map,key.split("\\."),0);
    }

    public static void main(String[] args) {
        String json = "{\n" +
                "   \"status\": 0,\n" +
                "   \"des\": \"\",\n" +
                "   \"data\": {\n" +
                "       \"businessLine\": 2,\n" +
                "       \"subBusinessLine\": null,\n" +
                "       \"actId\": 2,\n" +
                "       \"quantity\": 1,\n" +
                "       \"orderId\": \"123456\",\n" +
                "       \"paytime\": \"1617185887\",\n" +
                "       \"modTime\": \"1617186522\",\n" +
                "       \"payprice\": \"27.00\",\n" +
                "       \"profit\": \"0.00\",\n" +
                "       \"cpaProfit\": \"0\",\n" +
                "       \"sid\": \"sid123\",\n" +
                "       \"appkey\": \"appkey\",\n" +
                "       \"smstitle\": \"xx店\",\n" +
                "       \"status\": 8,\n" +
                "       \"tradeTypeList\": [\n" +
                "           1\n" +
                "       ],\n" +
                "       \"riskOrder\": 0,\n" +
                "       \"refundprofit\": \"-1.6200\",\n" +
                "       \"cpaRefundProfit\": \"0\",\n" +
                "       \"refundInfoList\": [\n" +
                "           {\n" +
                "               \"id\": \"123\",\n" +
                "               \"refundPrice\": \"27.00\",\n" +
                "               \"refundTime\": \"1617186522\",\n" +
                "               \"refundType\": 2\n" +
                "           }\n" +
                "       ],\n" +
                "       \"refundProfitList\": [\n" +
                "           {\n" +
                "               \"id\": \"123\",\n" +
                "               \"refundProfit\": \"-1.6200\",\n" +
                "               \"refundFinishTime\": \"1617186522\",\n" +
                "               \"type\": 1\n" +
                "           }\n" +
                "       ],\n" +
                "       \"extra\": null\n" +
                "   }\n" +
                "}";
        System.out.println(JsonUtils.getValue(json, "data.status"));
    }

}
